package utils

import (
	"crypto/md5"
	"encoding"
	"encoding/hex"
	"fmt"
	"hash"
)

// SerializableMD5 支持序列化的 MD5 hasher（使用标准库的 BinaryMarshaler 接口）
type SerializableMD5 struct {
	hash.Hash
}

// NewSerializableMD5 创建新的可序列化 MD5 hasher
func NewSerializableMD5() *SerializableMD5 {
	return &SerializableMD5{
		Hash: md5.New(),
	}
}

// Serialize 序列化状态为字节数组
func (s *SerializableMD5) Serialize() ([]byte, error) {
	marshaler, ok := s.Hash.(encoding.BinaryMarshaler)
	if !ok {
		return nil, fmt.Errorf("hash does not implement encoding.BinaryMarshaler")
	}
	return marshaler.MarshalBinary()
}

// Deserialize 从字节数组反序列化状态
func (s *SerializableMD5) Deserialize(data []byte) error {
	unmarshaler, ok := s.Hash.(encoding.BinaryUnmarshaler)
	if !ok {
		return fmt.Errorf("hash does not implement encoding.BinaryUnmarshaler")
	}
	return unmarshaler.UnmarshalBinary(data)
}

// SerializeHex 序列化为十六进制字符串（用于数据库存储）
func (s *SerializableMD5) SerializeHex() (string, error) {
	data, err := s.Serialize()
	if err != nil {
		return "", err
	}
	return hex.EncodeToString(data), nil
}

// DeserializeHex 从十六进制字符串反序列化
func (s *SerializableMD5) DeserializeHex(hexStr string) error {
	data, err := hex.DecodeString(hexStr)
	if err != nil {
		return err
	}
	return s.Deserialize(data)
}

// RestoreFromHex 从十六进制字符串创建并恢复 MD5 hasher
func RestoreMD5FromHex(hexStr string) (*SerializableMD5, error) {
	smd5 := NewSerializableMD5()
	if err := smd5.DeserializeHex(hexStr); err != nil {
		return nil, err
	}
	return smd5, nil
}
